#pragma once


//组件：
//消息队列 or 消息循环
//
//用法：
//1. Loop<T> loop;
//2. loop.registhandler;消费者，处理队列
//3. loop.start();
//
//4. loop.post(e); 生产者，添加元素



#include <memory>
#include <thread>
#include <functional>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <iostream>

using namespace std;



class BaseLoop
{
	public:
		virtual void stop()=0;
		virtual bool start()=0;
        virtual void send(void *)=0;	
};

template<typename T>
class Loop:public BaseLoop
{
	using HandleCB = function<void(T&)>;

	public:
		Loop(){ bStop = false; }
		void stop();
		bool start();
		void registhandler(HandleCB cb);
		void post(T);
        virtual ~Loop(){};
        void send(void*);

	private:
		thread mThread;
		queue<T> mqueue;
		mutex mlock;
		condition_variable mCond;
		bool bStop;
		HandleCB handlemessage;

		void loop();
};


template<typename T>
bool Loop<T>::start()
{
	cout<<"Loop_starting!"<<endl;
	mThread = std::thread(&Loop<T>::loop,this);
    return true;
}

template<typename T>
void Loop<T>::stop(){
	mCond.notify_one();
	bStop=true;
	mThread.join();
	cout<<"join okay"<<endl;
}

template<typename T>
void Loop<T>::loop()
{
	while(1)
	{
		//lock
		{
		unique_lock<mutex> _l(mlock);	
		int size = mqueue.size();
		if(size>0){
			T &e=mqueue.front();
			handlemessage(e);
			mqueue.pop();
		}else {	
			mCond.wait(_l);
		}
		}
		if(bStop)
			break;

	}
}

template<typename T>
void Loop<T>::post(T t){
	unique_lock<mutex> _l(mlock);
	mqueue.push(t);
	mCond.notify_one();
}

template<typename T>
void Loop<T>::send(void* data){
}

template<typename T>
void Loop<T>::registhandler(HandleCB cb)
{
	handlemessage = cb;
}


//loopmanager: 管理各种业务loop线程
class LoopManager{
    
    vector<BaseLoop*> mLoops;

    public:
        static LoopManager& GetInstance();
        void registloop(std::string loopname);
        BaseLoop* getloop(std::string loopname);
        void start();
};





